// 文件名：flat_map_error_codes.cpp
// 目的：用 std::flat_map 实现错误码与名称的双向查询，并演示边界查找与异构查找。
// 要点（int -> string）：
//   - 初始化平铺映射 errors，按 code 升序维护；
//   - find(code)：O(log N) 精确查找，返回名称或 <unknown>；
//   - upper_bound(450)：找到第一个“> 450”的迭代器，--it 得到“<= 450”的最大已知码；
// 要点（string -> int 异构查找）：
//   - 使用透明比较器 std::less<>（第三模板参数），支持用 std::string_view 直接查找，避免临时分配；
//   - nameToCode.find(std::string_view) 返回对应 code 或 <unknown>。
// 适用性：flat_map 迭代/扫描性能与空间局部性更优，适合只读或少量更新的枚举表/配置表。
// 注意：#include <flat_map> 需实现支持（C++23 或供应商扩展；可用 Boost.Container 兜底）。

#include <flat_map>
#include <iostream>
#include <string>
#include <string_view>

int main() {
    // 错误码 -> 文本描述（按 key 升序）
    std::flat_map<int, std::string> errors = {
        {100, "Continue"},
        {200, "OK"},
        {301, "Moved Permanently"},
        {400, "Bad Request"},
        {401, "Unauthorized"},
        {404, "Not Found"},
        {500, "Internal Server Error"}
    };

    // 单码查询
    auto describe = [&](int code) {
        auto it = errors.find(code);
        if (it == errors.end()) {
            std::cout << code << ": <unknown>\n";
        } else {
            std::cout << code << ": " << it->second << '\n';
        }
    };

    describe(200);
    describe(404);
    describe(418);

    // 边界查找：不大于 450 的最大已知错误码
    std::cout << "Highest known code <= 450:\n";
    auto it = errors.upper_bound(450);
    if (it == errors.begin()) {
        std::cout << "  None\n";
    } else {
        --it;
        std::cout << "  " << it->first << " -> " << it->second << '\n';
    }

    // 名称 -> 错误码（透明比较器支持 string_view 异构查找）
    std::flat_map<std::string, int, std::less<>> nameToCode = {
        {"Continue", 100},
        {"OK", 200},
        {"Not Found", 404}
    };

    auto lookupName = [&](std::string_view name) {
        auto itName = nameToCode.find(name); // 无需构造 std::string
        if (itName == nameToCode.end()) {
            std::cout << name << " -> <unknown>\n";
        } else {
            std::cout << name << " -> " << itName->second << '\n';
        }
    };

    lookupName("OK");
    lookupName("Internal Server Error");

    return 0;
}